package me.sdevil507.supports.shiro.filter;

import lombok.extern.slf4j.Slf4j;
import me.sdevil507.supports.helper.JsonResponseHelper;
import me.sdevil507.supports.result.ApiResultDTO;
import me.sdevil507.supports.result.ApiResultGenerator;
import me.sdevil507.supports.shiro.enums.LoginChannel;
import me.sdevil507.supports.shiro.session.ShiroSessionHelper;
import me.sdevil507.supports.status.ApiStatusCode;
import org.apache.shiro.web.filter.authc.UserFilter;
import org.apache.shiro.web.util.WebUtils;
import org.springframework.util.StringUtils;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 机构端用户的UserFilter
 *
 * @author sdevil507
 */
@Slf4j
public class OrgUserFilter extends UserFilter {

    @Override
    protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) {
        if (request instanceof HttpServletRequest) {
            // 校验如果是options请求,则放行
            String options = "OPTIONS";
            if (((HttpServletRequest) request).getMethod().toUpperCase().equals(options)) {
                return true;
            }
        }

        // 获取当前token的登录渠道
        if (StringUtils.isEmpty(ShiroSessionHelper.getChannel())) {
            return super.isAccessAllowed(request, response, mappedValue);
        }

        LoginChannel loginChannel = LoginChannel.valueOf(ShiroSessionHelper.getChannel());

        // 如果不是机构入口访问
        if (!loginChannel.equals(LoginChannel.ORG) && !loginChannel.equals(LoginChannel.IFRAME)  ) {
            return false;
        }

        return super.isAccessAllowed(request, response, mappedValue);
    }

    /**
     * 如果访问不通过,返回401错误码
     *
     * @param request  请求
     * @param response 响应
     * @return 执行反馈
     */
    @Override
    protected boolean onAccessDenied(ServletRequest request, ServletResponse response) {
        // 设置返回
        HttpServletResponse httpServletResponse = WebUtils.toHttp(response);
        HttpServletRequest httpServletRequest = WebUtils.toHttp(request);
        String token = httpServletRequest.getHeader("token");
        log.debug("经过filter请求地址:[" + httpServletRequest.getRequestURI() + "],携带token为:[" + token + "]");
        ApiResultDTO apiResultDTO;
        if (StringUtils.isEmpty(token)) {
            // 如果未携带令牌
            log.info("请求未携带身份令牌token!");
            apiResultDTO = ApiResultGenerator.create(ApiStatusCode.ACCOUNT_UNLOGIN.getCode(), ApiStatusCode.ACCOUNT_UNLOGIN.getDescription());
        } else {
            // 如果携带了令牌,但是令牌已失效情况
            log.info("请求携带的身份令牌token=[{}]已失效!", token);
            apiResultDTO = ApiResultGenerator.create(ApiStatusCode.ACCOUNT_TOKEN_INVALID.getCode(), ApiStatusCode.ACCOUNT_TOKEN_INVALID.getDescription());
        }
        JsonResponseHelper.exec(httpServletResponse, HttpServletResponse.SC_UNAUTHORIZED, apiResultDTO);
        return false;
    }
}
